﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Modeling;
using VsxFactory.Modeling.VisualStudio;
using VsxFactory.Modeling.Strategies.Rules;

namespace VsxFactory.Modeling.Strategies
{
    /// <summary>
    /// Interface à implémenter par les stratégies
    /// </summary>
    public interface IGenerationStrategy : IStrategy
    {
        /// <summary>
        /// La stratégie est initialisé à partir d'un document normal.
        /// </summary>
        /// <param name="host">Le hoster de stratégies</param>
        /// <param name="node">Noeud du document</param>
        /// <returns>true si l'initialisation s'est bien passée</returns>
        bool Initialize(IStrategiesHost host, IServiceProvider serviceProvider, IVsProjectFileItem node);
        /// <summary>
        /// Méthode appelée lors de l'ouverture d'un document
        /// </summary>
        /// <param name="document"></param>
        void OnDocumentSaved(IVsProjectFileItem document);
        /// <summary>
        /// Méthode appelée lors de la fermeture d'un document
        /// </summary>
        /// <param name="document"></param>
        /// <returns>true si il faut supprimer l'instance de la stratégie, false pour la conserver active.</returns>
        /// <remarks>
        /// Si la méthode renvoie true, il faut s'assurer que le provider ne crée pas de nouvelle instance à chaque ouverture
        /// de document.
        /// </remarks>
        bool OnDocumentClosed(IVsProjectFileItem document);
        /// <summary>
        /// Cette méthode est appelée quand l'utilisateur force une regénération
        /// </summary>
        /// <param name="document">Document</param>
        void GenerateArtifacts(IVsProjectFileItem document);
        /// <summary>
        /// Création de l'élément fournissant les informations nécessaires à la génération
        /// </summary>
        Func<IStrategyContext, ModelElement, GenerationSpec> CreateGenerationSpec { get; set; }
    }

    /// <summary>
    /// Provider de stratégie
    /// </summary>
    public interface IStrategyProvider
    {
        /// <summary>
        /// Création de la stratégie correspondant au document qui vient d'être ouvert.
        /// </summary>
        /// <param name="item"></param>
        /// <returns>Une instance de stratégie ou null si pas de stratégie pour ce document</returns>
        /// <remarks>
        /// Il ne peut y avoir qu'une seule instance de stratégie par document ouvert.
        /// </remarks>
        IStrategy CreateStrategy(IVsProjectFileItem item, Store store);
        /// <summary>
        /// Permet de valider si la stratégie peut s'appliquer sur un fichier
        /// </summary>
        /// <param name="host"></param>
        /// <param name="serviceProvider"></param>
        /// <returns>true si la stratégie peut s'activer, false sinon</returns>
        bool Activate(IStrategiesHost host, IServiceProvider serviceProvider);
        /// <summary>
        /// Fermeture d'un projet. Permet de libérer des ressources spécifiques au provider
        /// </summary>
        /// <param name="serviceProvider"></param>
        void Desactivate(IServiceProvider serviceProvider);
    }

    public interface IPostBuildStrategy : IStrategy
    {
        void Execute(IServiceProvider serviceProvider, VsxFactory.Modeling.VisualStudio.Synchronization.BuildCompleteEventArgs e);
    }

    public interface IProjectGenerationStrategy : IStrategy
    {
        void GenerateProjects();
        void Initialize(IStrategiesHost host, Store store);
    }
}

